﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using algorithms;
using snat.model;

namespace gui {
    /// <summary>
    /// Interaction logic for FactorySelectBox.xaml
    /// This box is presented directly after the InitialiseBox, to allow
    /// the user to select a node factory method.
    /// </summary>
    public partial class FactorySelectBox : Window {

        public ObservableCollection<FactoryItem> FactoriesList {
            get { return FactorySelectListInfo.Instance.FactoriesList; }
            set { FactorySelectListInfo.Instance.FactoriesList = value; }
        }
        public static FactoryItem SelectedFactory;
        public ObservableCollection<AlgorithmItem> AlgorithmsList { get; private set; }

        public FactorySelectBox(ObservableCollection<AlgorithmItem> list) {
            AlgorithmsList = list;
            FactoriesList = new ObservableCollection<FactoryItem>();
            InitializeComponent();

            // Setup List Binding
            FactorySelectListInfo._Dispatcher = this.Dispatcher;
            this.DataContext = FactorySelectListInfo.Instance;

            // Build factory list
            bool first = true;
            foreach (KeyValuePair<string, INodeFactory> f in NodeFactorySet.Instance) {
                if (f.Key.Contains("Default") && first == true) {
                    SelectedFactory = new FactoryItem(f.Value, f.Key, true);
                    FactoriesList.Add(SelectedFactory);
                    first = false;
                } else {
                    FactoriesList.Add(new FactoryItem(f.Value, f.Key, false));
                }
            }

            // Check to make sure something is selected if we have a non empty list
            if (SelectedFactory == null && FactoriesList.Count > 0) {
                FactoriesList[0].Selected = true;
                SelectedFactory = FactoriesList[0];
            }

            // Make this window the topmost window
            this.Topmost = true;
        }

        // On Initialise button clicked
        private void Initialise(object sender, RoutedEventArgs e) {
            if (FactoriesList.Count > 0) {

                if (NetworkModelConnect.IsConnected) {

                    // Create Loading Box
                    LoadingBox box = new LoadingBox("Building Network Model.");
                    box.Show();

                    // Initialise Network Model
                    NetworkModelConnect.Instance.Init(SelectedFactory.Factory, AlgorithmsList);

                    this.Close();

                } else {
                    // Tape Has Not Loaded therefore we cannot attempt to re-initialise the network model
                    MessageBox.Show("Warning : Factories can only be selected on a dataset once a database connection has been established, and before the dataset has begun playing. Please reinitialise.", "Warning", MessageBoxButton.OK, MessageBoxImage.Error);
                    ConnectBox box = new ConnectBox();
                    box.Show();
                    this.Close();
                }


            } else {
                MessageBox.Show("Please select an appropriate node factory.", "Warning", MessageBoxButton.OK, MessageBoxImage.Exclamation);
            }
        }

        // Enforce only single selection
        private void CheckBox_Checked(object sender, RoutedEventArgs e) {
            // Find newly selected
            foreach (FactoryItem f in FactoriesList) {
                if (f.Name != SelectedFactory.Name && f.Selected == true) {
                    SelectedFactory = f;
                    break;
                }
            }
            // Clear any other selected
            foreach (FactoryItem f in FactoriesList) {
                if (f.Name != SelectedFactory.Name && f.Selected == true) f.Selected = false;
            }
        }
        private void CheckBox_Unchecked(object sender, RoutedEventArgs e) {
            // Find the element just unselected, and select it again
            SelectedFactory.Selected = true;
        }


    }
}
